<?php

//require_once 're/Type/Scalar.php';
require_once 'standard/re/Scalar.php';
class re_Test_Rational extends re_Scalar
{

	public function _declarePossRep(){
		
		return array(
			'decimal'=>array(
				'decimal'=>'' //'' means any type
			),
			'hex'=>array(
				'hex'=>''
			)
		);
	}
	
	public function _sr( $recurse = FALSE ){
	
		return $this->theDecimal();
	}
	
	public function thehex(){
	
		return $this->_getThe("hex");
	}

	public function thedecimal(){
	
		return $this->_getThe("decimal");
	}
	
	protected function _decimal( $decimal ){
	
		$this->_setThe("decimal", (double)$decimal);	
	}
	
	protected function _hex( $hex ){
	
		$this->_setThe("hex", $hex);
	}
	
	protected function _convert($requestedCompName, $selectorUsed){
		
		switch( $selectorUsed ){

			case "hex":
				$hex = strtoupper($this->thehex());
				switch( $requestedCompName ){
					case "decimal" :
						return round(hexdec(str_replace(".", "", $hex)) / hexdec(pow(10, strlen(strstr($hex, '.'))-1)), 4);
					break;
				}

			break;
			
			case "decimal" :
				$decimal = (string)$this->thedecimal();
				switch( $requestedCompName ){
					case "hex" :
						$d = explode(".", $decimal);
						$p1 = 0; $p2 = 0;
						if( isset($d[0]) ){
							$p1 = dechex($d[0]);
						}
						$max = 8;
						if( isset($d[1]) ){
							$len = ( ($len = strlen((string)$d[1]))  && $len > $max ) ? $max : $len;
							$d[1] = substr($d[1], 0, $len);
							$d[1] = dechex($d[1]) .  str_repeat("0", $len);
							
							$p2 = rtrim(dechex(floor(hexdec($d[1]) / pow(10, $len))), '0');
						}
						return ( ($p1 == '0' && $p2 == '0') ? "0" : "$p1.$p2" );
					break;
				}
		}
	}
	
	
	public function plus(re_Test_Rational $r){
	
		return self::value(
			$this->thedecimal() + $r->thedecimal()
		);
	}
	
	public function times( re_Test_Rational $r ){
		
		return self::value(
			$this->thedecimal() * $r->thedecimal()
		);
	}

	public function divide(re_Test_Rational $r){
	
		return self::value(
			$this->thedecimal() / $r->thedecimal()
		);
	}
	
	public function cos(){
		
		return self::value(
			cos($this->thedecimal())
		);
	}

	public function sin(){
	
		return self::value(
			sin($this->thedecimal())
		);
	}
	
	public function raise($power){
	
		return self::value(
			pow($this->thedecimal(), $power)
		);
	}
	
	public function sqrRt(){
	
		return self::value(
			sqrt($this->thedecimal())
		);
	}
	
	public function arcTan(){
	
		return self::value(
			atan($this->thedecimal())
		);
	}
	
	static public function value($selectorArgs, $selector){
		
		return re::select(
			__CLASS__,
			$selectorArgs,
			'decimal'
		);
	}	
}